import Axios, {
  type AxiosInstance,
  type AxiosError,
  type AxiosResponse,
  type AxiosRequestConfig
} from "axios";
import { ContentTypeEnum, ResultEnum } from "@/enums/request-enum";
import NProgress from "../progress";
import { showFailToast } from "vant";
import "vant/es/toast/style";
import { useUserStore } from "@/store/useUserStore";
import router from "@/router";
import { useLocationParams } from "@/store/useLocationStore";
const baseURL =
  import.meta.env.VITE_ENV === "development"
    ? "/dev-api"
    : import.meta.env.VITE_BASE_API;
// 默认 axios 实例请求配置
const configDefault = {
  headers: {
    // "Content-Type": ContentTypeEnum.JSON
    // Authorization:
    // "Bearer eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiJmOTdjM2JlYjBmMjA0ZmU5OTk5MDM3MzgxY2ZiZmY1NCIsInVzZXIiOiJhZG1pbiIsInN1YiI6ImFkbWluIn0.x2iAfzljNGWF8wfjw_hauHFl0GneajQrWcTj_7RFDnGljSwKN0Kv0QFCNuEU2Kofk1q-t5-uzjH8XcPDiJOIGw"
  },
  // baseURL: baseURL
  baseURL: import.meta.env.VITE_BASE_API
};

export const createErrorConf = (name: string, message: string) => {
  const { getAllParams } = useLocationParams();
  return {
    name: name,
    query: { ...getAllParams(), message: message }
  };
};
class Http {
  // 当前实例
  private static axiosInstance: AxiosInstance;
  // 请求配置
  private static axiosConfigDefault: AxiosRequestConfig;

  // 请求拦截
  private httpInterceptorsRequest(): void {
    Http.axiosInstance.interceptors.request.use(
      config => {
        NProgress.start();
        // 发送请求前，可在此携带 token
        const useStore = useUserStore();
        const { getAllParams } = useLocationParams();
        if (config.headers["No-Auth"]) {
          return config;
        }
        if (useStore.isAuthenticated()) {
          // } else {
          config.headers["Authorization"] = useStore.user.token;
        } else {
          router.replace(createErrorConf("Login", "请先登录"));
          return Promise.reject("请先登录");
        }
        return config;
      },
      (error: AxiosError) => {
        showFailToast(error.message);
        return Promise.reject(error);
      }
    );
  }

  // 响应拦截
  private httpInterceptorsResponse(): void {
    Http.axiosInstance.interceptors.response.use(
      (response: AxiosResponse) => {
        NProgress.done();
        const { getAllParams } = useLocationParams();
        // 与后端协定的返回字段
        const { code, data, message } = response.data;
        // const { message } = response.data;
        // 判断请求是否成功
        const isSuccess =
          data &&
          Reflect.has(response.data, "code") &&
          (code === ResultEnum.SUCCESS || code === ResultEnum.SUCCESS2);
        if (isSuccess) {
          return data;
        } else if (
          code === ResultEnum.UNAUTHORIZED ||
          code === ResultEnum.TIMEOUT ||
          code === ResultEnum.UNAUTHORIZED2
        ) {
          // 处理请求错误
          // showFailToast(message);
          const { clearUser } = useUserStore();
          clearUser();
          location.reload();
          // router.push(createErrorConf("Login", "请先登录"));
        } else if (
          code === ResultEnum.ERROR_BUSINESS ||
          code === ResultEnum.ERROR_SYSTEM ||
          code === ResultEnum.ERROR_PARAM
        ) {
          router.push(createErrorConf("Error", message));
          return;
        }
        return Promise.reject(response.data);
      },
      (error: AxiosError) => {
        NProgress.done();
        // 处理 HTTP 网络错误
        let message = "";
        // HTTP 状态码
        const status = error.response?.status;
        const data: any = error.response?.data;
        if (status == 500) {
          const code = data.code;
          if (
            code == ResultEnum.ERROR_BUSINESS ||
            code == ResultEnum.ERROR_SYSTEM ||
            code == ResultEnum.ERROR_PARAM
          ) {
            router.push(createErrorConf("Error", data.message));
            return;
          }
        }
        if (data && data.status == 500) {
          const { getAllParams } = useLocationParams();
          router.push(createErrorConf("Error", "系统异常，请联系管理员！"));
          return Promise.reject(error);
        }
        switch (status) {
          case 400:
            message = "请求错误";
            break;
          case 401:
            message = "未授权，请登录";
            break;
          case 403:
            message = "拒绝访问";
            break;
          case 404:
            message = `服务地址无法访问: ${error.response?.config?.url}`;
            router.push(createErrorConf("Error", "服务地址无法访问"));
            break;
          case 408:
            message = "请求超时";
            break;
          case 500:
            message = "服务器内部错误";
            break;
          case 501:
            message = "服务未实现";
            break;
          case 502:
            message = "网关错误";
            break;
          case 503:
            message = "服务不可用";
            break;
          case 504:
            message = "网关超时";
            break;
          case 505:
            message = "HTTP版本不受支持";
            break;
          default:
            message = "网络连接故障";
        }
        if (import.meta.env.MODE === "development") {
          console.log(error);
          showFailToast(message);
        }
        return Promise.reject(error);
      }
    );
  }

  constructor(config: AxiosRequestConfig) {
    Http.axiosConfigDefault = config;
    Http.axiosInstance = Axios.create(config);
    this.httpInterceptorsRequest();
    this.httpInterceptorsResponse();
  }

  // 通用请求函数
  public request<T>(paramConfig: AxiosRequestConfig): Promise<T> {
    const config = { ...Http.axiosConfigDefault, ...paramConfig };
    return new Promise((resolve, reject) => {
      Http.axiosInstance
        .request(config)
        .then((response: any) => {
          resolve(response);
        })
        .catch(error => {
          reject(error);
        });
    });
  }
}

export const http = new Http(configDefault);
